<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>key的原理</title>
        <!-- 引入Vue -->
        <script type="text/javascript" src="../js/vue.js"></script>
    </head>
    <body>
        <h1>面试题：react、vue中的key有什么作用？key的内部原理</h1>
        <hr>
        <h2>1. 虚拟DOM中key的作用</h2>
        <p>key是虚拟DOM对象的标识，当状态中的数据发生变化时，Vue会根据【新数据】生成【新的虚拟DOM】，
            随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较，比较规则如下：
        </p>

        <h2>2. 对比规则</h2>
        <p>2.1 旧虚拟DOM中找到了与新虚拟DOM相同的key：</p>
        <p>2.1.1 若虚拟DOM中内容没变，直接使用之前的真实DOM</p>
        <p>2.1.2 若虚拟DOM中内容变了，则生成新的真实DOM，随后替换掉页面中之前的真实DOM。</p>

        <h2>3. 用index作为key可能会引发的问题</h2>
        <p>3.1 若对数据进行：逆序添加、逆序删除等破坏顺序操作，会产生没有必要的真实DOM更新 ==> 界面效果没有问题，但效率低。</p>
        <p>3.2 如果结构中还包含输入类的DOM：会产生错误DOM更新 ==> 界面有问题。</p>
        <img src="../images/index作为key.png" alt="">

        <h2>4. 开发中如何选择key?</h2>
        <p>4.1 最好使用每条数据的唯一标识作为key，比如id、手机号、身份证号、学号等唯一值。</p>
        <p>4.2 如果不存在对数据的逆序添加、逆序删除等破环顺序操作，仅用于渲染列表用于展示，使用index作为key是没有问题的。</p>
        <img src="../images/id作为key.png" alt="">


        <div id="root">
            <h2>人员列表（遍历数组）</h2>
            <ul>
                <li v-for="(p, index) of persons" :key="p.id">
                    {{p.name}}: {{p.age}}
                    <input type="text" name="" id="">
                </li>
            </ul>
            <button @click.once="add">增加一个老刘</button>
        </div>
        <script type="text/javascript">
            Vue.config.productionTip = false    // 阻止Vue在启动时生成生产提示

            // 创建Vue实例，开端
            new Vue({
                el: '#root', // el用于指定当前Vue实例为哪个容器服务，值通常为css选择器字符串。
                data: {     // data中用于存储数据，数据供el指定的容器去使用
                    persons: [
                        {
                            id: '001',
                            name: "张三",
                            age: 18
                        },
                        {
                            id: '002',
                            name: "李四",
                            age: 18
                        },
                        {
                            id: '003',
                            name: "王五",
                            age: 18
                        }
                    ],
                },
                methods: {
                    add(){
                        const p = {id:'004', name: "老刘", age: 50}
                        this.persons.unshift(p)
                    }
                },
            })
        </script>
    </body>
</html>
